const jwt = require('jsonwebtoken')
const CryptoJS = require('crypto-js')
const { getAll, getById, exec } = require('../db/index.js')

// 定义常量
const screat = 'smartcity'
const acessTokenExpire = 10 * 60 //10分钟
const refreshTokenExpire = 60 * 60 * 24 * 2 //2天

// 查询用户名是否存在
async function queryuser(req, res) {
  const { logusername, regusername, type } = req.body
  // 查询数据库所有用户名

  let sql = `select user_name from gg_users`
  const users = await getAll(sql)
  const allusername = users.map((item) => item.user_name)
  // 存在则提示重复已注册，是否登录，不存则注册

  if (type == 'login') {
    if (allusername.includes(logusername)) {
      return res.send({
        code: 0,
        valid: true,
      })
    }
    res.send({
      code: 0,
      valid: false,
    })
  } else {
    if (allusername.includes(regusername)) {
      return res.send({
        code: 0,
        valid: false,
      })
    }
    res.send({
      code: 0,
      valid: true,
    })
  }
}

// 注册
async function Register(req, res) {
  const { username, password, useremail } = req.body
  // 操作数据库
  let newsql = `insert into gg_users (user_name,user_password,user_email,user_type) values ('${username}','${password}','${useremail}',"all")`
  let { insertId } = await exec(newsql)
  // 返回结果
  res.send({
    code: 0,
    message: '注册成功',
    result: insertId,
  })
}

// 登录
async function Login(req, res) {
  try {
    const { username, password, timestamp } = req.body
    let usersql = `select user_password, user_onlinestatus from gg_users where user_name = '${username}'`
    const data = await exec(usersql)
    console.log(data)
    let newPas = CryptoJS.MD5(timestamp + data[0].user_password).toString()
    if (password != newPas) {
      return res.send({
        code: 400,
        message: '密码错误',
        result: {},
      })
    }
    if (data[0].user_onlinestatus == '-99999') {
      return res.send({
        code: 400,
        message: '黑名单请联系管理员解除!',
        result: {},
      })
    }
    const access_token = await generateAccessToken(username)
    const refresh_token = await generateRefreshToken(username)
    let newsql = `update gg_users set user_onlinestatus = 'yes' where user_name='${username}'`
    console.log(newsql)
    await exec(newsql)
    res.send({
      code: 0,
      message: '登陆成功',
      result: {
        access_token,
        refresh_token,
      },
    })
  } catch (error) {
    return res.send({
      code: 400,
      message: 'something error',
      result: { error },
    })
  }
}

// 登出
async function Logout(req, res) {
  // 解析参数
  try {
    let { username } = req.params
    let sql1 = `select user_onlinestatus from gg_users where user_name = '${username}'`
    const data1 = await exec(sql1)
    if (data1[0].user_onlinestatus == '-99999') {
      return res.send({
        code: 0,
        message: '登出成功',
        result: '',
      })
    }
    let sql = `update gg_users set user_onlinestatus = 'no'  where user_name='${username}'`
    console.log(sql)
    await exec(sql)
    // 返回数据
    res.send({
      code: 0,
      message: '登出成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '登出失败',
      result: err,
    })
  }
}

// 下线用户
async function offline(req, res) {
  // 解析参数
  try {
    let { id } = req.params
    let sql = `update gg_users set user_onlinestatus = '-99999'  where user_id= ${id} `

    await exec(sql)
    // 返回数据
    res.send({
      code: 0,
      message: '下线成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '下线失败',
      result: err,
    })
  }
}

// 解除用户下线状态removestatus
async function removestatus(req, res) {
  // 解析参数
  try {
    let { id } = req.params
    let sql = `update gg_users set user_onlinestatus = 'no'  where user_id= ${id} `

    await exec(sql)
    // 返回数据
    res.send({
      code: 0,
      message: '解除成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '解除失败',
      result: err,
    })
  }
}

// 修改密码
async function Changepsw(req, res) {
  try {
    const { oldPsw, newPas, username } = req.body
    let usersql = `select user_password from gg_users where user_name = '${username}'`
    const data = await exec(usersql)
    if (oldPsw != data[0].user_password) {
      return res.send({
        code: 400,
        message: '原始密码错误',
        result: {},
      })
    }
    let changesql = `update gg_users set user_password='${newPas}' where user_name = '${username}'`
    await exec(changesql)
    res.send({
      code: 0,
      message: '修改成功',
      result: {},
    })
  } catch (error) {
    return res.send({
      code: 400,
      message: 'something error',
      result: { error },
    })
  }
}

// RefreshToken获取
async function generateRefreshToken(username) {
  let usersql = `select * from gg_users where user_name = '${username}'`
  const data = await exec(usersql)
  const payload = {
    sub: data[0].user_id,
    name: data[0].user_name,
    type: data[0].user_type,
  }

  const expiresIn = {
    expiresIn: refreshTokenExpire,
  }

  const refresh_token = jwt.sign(payload, screat, expiresIn)
  //   const decoded = jwt.verify(refresh_token, screat, { complete: true })
  //   const decoded2 = jwt.decode(refresh_token, screat, { complete: true })

  //   console.log(decoded, decoded2)
  //   redis_client.set(data[0].user_id.toString(), refresh_token)
  //   redis_client.expire(data[0].user_id.toString(), refreshTokenExpire)
  return refresh_token
}

// AccessToken获取
async function generateAccessToken(username) {
  let usersql = `select * from gg_users where user_name = '${username}'`
  const data = await exec(usersql)
  const payload = {
    sub: data[0].user_id,
    name: data[0].user_name,
    type: data[0].user_type,
  }
  const expiresIn = {
    expiresIn: acessTokenExpire,
  }
  const access_token = jwt.sign(payload, screat, expiresIn)

  //   redis_client.set(data[0].user_id.toString(), access_token)
  //   redis_client.expire(data[0].user_id.toString(), acessTokenExpire)
  return access_token
}

// 验证token
async function verifyToken(req, res) {
  try {
    if (req.headers.access_token) {
      const acctoken = req.headers.access_token
      const decode = jwt.verify(acctoken, screat)
      if (decode.name) {
        return res.send({
          code: 0,
          message: 'taken validate success',
        })
      }
    } else {
      const reftoken = req.headers.refresh_token

      const decode = jwt.verify(reftoken, screat)

      if (decode.name) {
        const newAcess = await generateAccessToken(decode.name)
        return res.send({
          code: 0,
          message: 'taken validate success',
          result: newAcess,
        })
      }
    }
  } catch (error) {
    return res.send({
      code: 400,
      message: 'something error',
      result: error,
    })
  }
}

// 分组统计饼状图
async function getgroupNum(req, res) {
  // 操作数据库
  let sql = `select user_add as name, count(*) as value from gg_users group by user_add`

  try {
    // 正常的情况
    const resData = await exec(sql)
    res.send({
      code: 0,
      message: '获取成功',
      result: resData,
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '获取失败',
      result: err,
    })
  }
}

// 用户注册时间
async function getuserRtime(req, res) {
  // 操作数据库
  try {
    let sql = `select DATE_FORMAT(user_registTime, '%Y,%m,%d')  as days ,count(*) as value from gg_users  GROUP BY  DATE_FORMAT(user_registTime, '%Y,%m,%d')`
    let resdata = await getAll(sql) // { total: 10 }

    // 返回数据
    res.send({
      code: 0,
      message: '获取成功',
      result: resdata,
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '获取失败',
      result: err,
    })
  }
}

// 用户列表
async function getuserList(req, res) {
  // 解析参数
  try {
    const {
      page = 1,
      size = 10,
      sortOrder = 'asc',
      sort = 'user_id',
      user_type,
    } = req.query
    // 分页的公式: 偏移量 = (当前页码数 - 1)*每页显示数ORDER BY Company DESC
    let offset = (page - 1) * size
    // 操作数据库
    let sql2 = `select count(*) as total from gg_users`
    let { total } = await getById(sql2) // { total: 10 }
    var sql = ''
    if (user_type) {
      sql = `select * from gg_users where user_type= ${user_type} order by ${sort} ${sortOrder} limit ${offset}, ${size} `
    } else {
      sql = `select * from gg_users order by ${sort} ${sortOrder} limit ${offset}, ${size} `
    }

    const data = await getAll(sql)

    // 返回数据
    res.send({
      code: 0,
      message: '获取list成功',
      result: {
        total: total,
        rows: data,
      },
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '获取失败',
      result: err,
    })
  }
}

// 添加用户
async function Addnew(req, res) {
  try {
    const { username, userpassword, useremail, usertype, useraddress } =
      req.body
    // 操作数据库
    let newsql = `insert into gg_users (user_name,user_password,user_email,user_type,user_add) values ('${username}','${userpassword}','${useremail}','${usertype}','${useraddress}')`
    let { insertId } = await exec(newsql)
    // 返回结果
    res.send({
      code: 0,
      message: '添加成功',
      result: insertId,
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '添加失败',
      result: err,
    })
  }
}

// 批量删除
async function delUsers(req, res) {
  // 解析参数
  try {
    const { ids } = req.body
    for (var item of ids) {
      // 操作数据库
      let sql = `delete from gg_users where user_id=${item}`
      await exec(sql)
    }
    // 返回数据
    res.send({
      code: 0,
      message: '删除成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '删除失败',
      result: err,
    })
  }
}

// 根据id删除
async function delUserbyId(req, res) {
  // 解析参数
  try {
    let { id } = req.params
    let sql = `delete from gg_users where user_id=${id}`

    console.log(sql)
    await exec(sql)

    // 返回数据
    res.send({
      code: 0,
      message: '删除成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '删除失败',
      result: err,
    })
  }
}

// 保存编辑
async function saveEdit(req, res) {
  try {
    const { user_id, user_name, user_email, user_type, user_add } = req.body

    // 操作数据库
    let newsql = `update gg_users set user_name='${user_name}',user_email='${user_email}',user_type='${user_type}',user_add='${user_add}' where user_id=${user_id}`
    await exec(newsql)
    // 返回结果
    res.send({
      code: 0,
      message: '修改成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '修改失败',
      result: err,
    })
  }
}

// 批量添加
async function newbyfile(req, res) {
  // 解析参数
  const { exceldata } = req.body
  const newdata = JSON.parse(exceldata)
  try {
    for (const item of newdata) {
      // 操作数据库
      let newsql = `insert into gg_users (user_name,user_password,user_email,user_type,user_add) values ('${item.user_name}','${item.user_password}','${item.user_email}','${item.user_type}','${item.user_add}')`
      await exec(newsql)
    }
    // 返回数据
    res.send({
      code: 0,
      message: '批量添加成功',
      result: '',
    })
  } catch (err) {
    // 异常的情况
    res.send({
      code: 100101,
      message: '批量添加失败',
      result: err,
    })
  }
}

module.exports = {
  Register,
  Login,
  generateAccessToken,
  Logout,
  queryuser,
  verifyToken,
  Changepsw,
  getgroupNum,
  getuserRtime,
  getuserList,
  Addnew,
  delUsers,
  delUserbyId,
  saveEdit,
  newbyfile,
  offline,
  removestatus,
}
